package com.common.android.ui.gif;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.text.TextUtils;
import android.util.Log;

import com.common.android.utils.DisplayUtil;
import com.common.android.utils.MD5ArithmeticUtils;
import com.common.android.utils.smiley.Smileyhelper;
import com.nostra13.universalimageloader.utils.StorageUtils;
import com.product.android.business.ApplicationVariable;
import com.product.android.business.config.Configuration;
import com.product.android.commonInterface.BaseCommonStruct;
import com.product.android.commonInterface.CIConst;
import com.product.android.commonInterface.CommonInterfaceManager;

/**
 * ClassName:GifCacheManager
 * Function: GIF动画所用的图片缓存管理类
 * Reason:	 
 * @author   cb		
 * @version  Ver 1.3.3_modularization
 * @Date	 2014	2014-3-11		下午5:26:51
 *
 * @see 	 
 */
public enum GifCacheManager {
	INSTANCE();
	private static final String DIR="gifcache";
	private static final long MAX_MEM=4*1024*1024;		//分配的最大缓存空间
	private static final int MAX_WIDTH=120;
	private static final int MIN_WIDTH=30;
	private static final int MAX_THREAD_COUNT=10;
	private static final int MIN_CACHE_COUNT=5;
	private ArrayList<ICheckUsingKeyInterface> mCheckUsingKeyInterfaces=new ArrayList<ICheckUsingKeyInterface>();
	private Map<Object,Vector<GifFrame>> mMaps=new HashMap<Object, Vector<GifFrame>>();	//当前缓存的所有的动画帧数据
	private long mNowSize=0;		//当前已用的空间
	private ArrayList<Object> mInuseKeys=new ArrayList<Object>();	//正在使用的KEY列表
	private ScheduledExecutorService mExecutorService;
	private ArrayList<Object> mDecodingGifList=new ArrayList<Object>();	//正在解码的GIF对应的KEY列表，用于判断某个GIF是否正在解码
	private ArrayList<Object> mBrokenGifList=new ArrayList<Object>();			//无法解析的GIF列表
	private Map<Object,Bitmap> mLocalBitmaps=new HashMap<Object, Bitmap>();
	private ArrayList<Future<?>> mFutures=new ArrayList<Future<?>>();
	private volatile boolean mIsClearing=false;	//是否正在清理缓存
	private volatile boolean mIsActive=false;	//是否正被使用
	private int mMaxWidth=0;
	private int mMinWidth=0;
	private GifCacheManager(){
		mExecutorService=Executors.newScheduledThreadPool(MAX_THREAD_COUNT);
		mMinWidth=DisplayUtil.dip2px(ApplicationVariable.INSTANCE.applicationContext,MIN_WIDTH);
		mMaxWidth=DisplayUtil.dip2px(ApplicationVariable.INSTANCE.applicationContext,MAX_WIDTH);
	}
	
	/**
	 * @n<b>函数名称</b>     :put
	 * @brief 存入动画数据
	 * @version    Ver 1.3.3_modularization
	 * @param  @param key     存取数据的KEY，可能是一个资源ID，也可能是一个本地路径
	 * @param  @param frames
	 * @param  @return
	 * @return boolean
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:28:15      
	*/
	public void put(Object key,Vector<GifFrame> frames){
		if (frames==null || frames.isEmpty()){
			return;
		}
		if (!mMaps.containsKey(key)){
			//由于有一些图片可能被回收后又重新获取到，每次加入新的数据都要重新计算一下当前使用的缓存
			//鉴于一个用户在同一个聊天中使用的GIF图片不会太多，这样做对于效率不会有太大的影响。
			reCaculateCacheSize();
			if (mNowSize>=MAX_MEM && mMaps.size()>=MIN_CACHE_COUNT){
				//如果已用的空间大于允许的最大值，要去移除一些未使用的数据
				removeUnusedFrames();
			}
			if (mIsClearing){
//				Log.d("gifview","cache is clear");
				return;
			}
			//存入数据，并计算当前已用的空间
			synchronized (mMaps) {
				if (mIsClearing){
//					Log.d("gifview","cache is clear");
					return;
				}
				mMaps.put(key, frames);	
			}
			synchronized (frames) {
				//获取磁盘缓存的目录
				File subDir=getDiskCacheDir(key);
				for (int i=0,count=frames.size();i<count;i++){
					Bitmap bitmap=frames.get(i).image;
					if (bitmap==null || bitmap.isRecycled()){
						continue;
					}
					//如果缓存的图片超过上限，把图片缩小
					bitmap=BitmapToolkit.zoomBitmap(bitmap, mMaxWidth, mMinWidth);
					frames.get(i).image=bitmap;
					frames.get(i).size=bitmap.getRowBytes()*bitmap.getHeight();
					mNowSize+=frames.get(i).size;
					String filename=subDir.getAbsolutePath()+Configuration.separatorChar+i;
					File file=new File(filename);
					try {
						if (!file.exists()){
							file.createNewFile();
							BitmapToolkit.saveBitmap(file,bitmap,CompressFormat.PNG);
						}else{
							if (file.length()==0){
								//文件保存失败，删除重新存一个
//								Log.d("gifview","saveBitmap fail:"+filename);
								file.delete();
								BitmapToolkit.saveBitmap(file,bitmap,CompressFormat.PNG);
							}
						}
						frames.get(i).path=filename;
					} catch (Exception e) {
//						Log.d("gifview","saveBitmap fail:"+filename);
						if (file.exists()){
							file.delete();
						}
						continue;
					}
					
				}
			}
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :setInuse
	 * @brief 设置当前的数据正在被使用
	 * @version    Ver 1.3.3_modularization
	 * @param  @param key
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:50:18      
	*/
	public void setInuse(Object key){
		if (key==null){
			return;
		}
//		Log.d("gif","setInuse:"+key.toString());
		synchronized (mInuseKeys) {
			if (mMaps.containsKey(key) && !mInuseKeys.contains(key)){
				mInuseKeys.add(key);
			}
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :removeUnUsedFrames
	 * @brief  从内存中移除未用到的数据
	 * @version    Ver 1.3.3_modularization
	 * @param  @return
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:31:45      
	*/
	private void removeUnusedFrames(){
		if (mMaps.size()<=mInuseKeys.size()){
			return;
		}
		Iterator<Entry<Object,Vector<GifFrame>>> iterator=mMaps.entrySet().iterator();
		//遍历所有的已存数据
		while (iterator.hasNext()){
			Entry<Object,Vector<GifFrame>> entry=iterator.next();
			Object key=entry.getKey();
			boolean inUsing=false;
			for (ICheckUsingKeyInterface keyInterface : mCheckUsingKeyInterfaces) {
				if (keyInterface.isKeyUsing(key)){
					//当前的数据正被使用，找下一个
					inUsing=true;
					break;
				}
			}
			if (inUsing){
				continue;
			}
//			Log.d("gifview","out of MAX_MEM，remove "+key);
			clearFrames(mMaps.get(key));
			//只回收图片，对象还留着
//			iterator.remove();
			mInuseKeys.remove(key);
			break;
		}
//		Log.d("gifview","after remove: ");
		while (iterator.hasNext()){
			Entry<Object,Vector<GifFrame>> entry=iterator.next();
			Object key=entry.getKey();
//			Log.d("gifview",key+":"+entry.getValue().size());
		}
		if (mNowSize>MAX_MEM && mMaps.size()>=MIN_CACHE_COUNT){
			removeUnusedFrames();
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :get
	 * @brief 根据的KEY获取对应的数据
	 * @version    Ver 1.3.3_modularization
	 * @param  @param key
	 * @param  @return
	 * @return Vector<GifFrame>
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:34:36      
	*/
	public Vector<GifFrame> get(Object key){
		//调用此方法即表明要使用缓存，不允许清理
		mIsActive=true;
		Log.d("gifview", "get:"+mIsActive);
		if (key==null || mIsClearing){
			//非法的key或者正在清理缓存
			if (mIsClearing){
				Log.d("gifview", "get while isClearing");	
			}
			return null;
		}
		Vector<GifFrame> frames=mMaps.get(key);
		boolean framesInvalid=false;
		if (frames!=null){
			if (frames.isEmpty()){
//				Log.d("gifview","frames empty:"+key);
				mMaps.remove(key);
			}else{
				for (GifFrame frame : frames) {
					if (frame.image==null || frame.image.isRecycled()){
						if (TextUtils.isEmpty(frame.path)){
							//图片不存在或者被回收且没有缓存路径
							Log.d("gifview","frames path:"+key+","+frames.indexOf(frame));
							framesInvalid=true;
							break;
						}else{
							try {
								Options opt=new Options();
								BitmapFactory.decodeFile(frame.path,opt);
								if (opt.outHeight<=0 ||opt.outWidth<=0){
									//图片不可用
									Log.d("gifview","bitmap invalid:"+key+","+frames.indexOf(frame));
									framesInvalid=true;
									break;
								}								
							} catch (Exception e) {
								framesInvalid=true;
								break;
							}
						}
					}
				}
			}
		}
		if (framesInvalid){
			mMaps.remove(key);
			mBrokenGifList.remove(key);
			mDecodingGifList.remove(key);
			mInuseKeys.remove(key);
			File file=getDiskCacheDir(key);
			if (file!=null && file.exists()){
				file.delete();
			}
			for (GifFrame frame : frames){
				if (frame!=null && frame.image!=null && !frame.image.isRecycled()){
					frame.image.recycle();
					frame.image=null;
				}
			}
			frames=null;
		}
		return frames;
	}
	
	/**
	 * @n<b>函数名称</b>     :clear
	 * @brief 清除数据（界面结束的时候要调）
	 * @version    Ver 1.3.3_modularization
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:36:16      
	*/
	public void clear(){
		if(mIsActive){
			//正在被使用，不清理
			Log.d("gifview", "cache still in use,can't be clear");
			return;
		}
		Log.d("gifview", "start clear cache");
		mIsClearing=true;
		mInuseKeys.clear();
		mBrokenGifList.clear();
		mDecodingGifList.clear();
//		for (Future<?> future:mFutures) {
//			//停掉所有的解码线程
//			if (!future.isDone()){
//				future.cancel(true);
//			}
//		}
//		mFutures.clear();
		synchronized (mMaps) {
			Iterator<Entry<Object,Vector<GifFrame>>> iterator=mMaps.entrySet().iterator();
			while (iterator.hasNext()){
				Entry<Object,Vector<GifFrame>> entry=iterator.next();
				if (entry==null){
					break;
				}
				Vector<GifFrame> frames=entry.getValue();
				clearFrames(frames);
			}
		}
		synchronized (mLocalBitmaps) {
			Iterator<Entry<Object,Bitmap>> iteratorBitmap=mLocalBitmaps.entrySet().iterator();
			while (iteratorBitmap.hasNext()){
				Entry<Object,Bitmap> entry=iteratorBitmap.next();
				if (entry==null){
					break;
				}
				Bitmap bmp=entry.getValue();
				if (bmp==null){
					continue;
				}
				bmp.recycle();
				iteratorBitmap.remove();
			}
		}
		mLocalBitmaps.clear();
		mNowSize=0;
		mIsClearing=false;
	}
	
	/**
	 * @n<b>函数名称</b>     :clearFrames
	 * @brief 清空某个动画帧数据集
	 * @version    Ver 1.3.3_modularization
	 * @param  @param frames
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-11下午5:40:50      
	*/
	private void clearFrames(Vector<GifFrame> frames){
		if (frames!=null && !frames.isEmpty()){
			for (GifFrame gifFrame : frames) {
				if (gifFrame.image!=null && !gifFrame.image.isRecycled()){
					gifFrame.image.recycle();
				}
				mNowSize-=gifFrame.size;
			}
//			frames.clear();
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :createNewFutureTask
	 * @brief 获取一个线程运行任务
	 * @version    Ver 1.3.3_modularization
	 * @param  @param task
	 * @param  @return
	 * @return Future<?>
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-13下午4:00:21      
	*/
	public Future<?> createNewFutureTask(Runnable task){
		return mExecutorService.submit(task);
	}
	
	/**
	 * @n<b>函数名称</b>     :clearInUseList
	 * @brief 清空在用的动画的KEY列表
	 * @version    Ver 1.3.3_modularization
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-13下午4:01:30      
	*/
	public void clearInUseList(){
		mInuseKeys.clear();
	}
	
	/**
	 * @n<b>函数名称</b>     :decodeGif
	 * @brief 解析GIF图片
	 * @version    Ver 1.3.3_modularization
	 * @param  @param generateId
	 * @param  @param key
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-13下午7:59:05      
	*/
	public synchronized void decodeGif(String generateId,Object key){
		if (mDecodingGifList.contains(key) ){
//			Log.d("gifview","key is still decoding:"+key);
			return;
		}
		if (mBrokenGifList.contains(key) ){
//			Log.d("gifview","key is broken:"+key);
			return;
		}
		mDecodingGifList.add(key);
		mExecutorService.submit(new runDecode(generateId,key));
//		Future<?> future=mExecutorService.submit(new runDecode(generateId,key));
//		if (!mFutures.contains(future)){
//			mFutures.add(future);
//		}
	}
	
	/**
	 * ClassName:runDecode
	 * Function: 解码线程
	 * Reason:	 
	 * @author   cb		
	 * @version  Ver 1.3.3_modularization
	 * @Date	 2014	2014-3-13		下午7:59:13
	 *
	 * @see 	 
	 */
	private class runDecode implements Runnable{
		private Object mKey;
		private String mGenerateId;
		public runDecode(String generateId,Object key){
//			Log.d("gifview","=========runDecode:"+generateId+",key="+key);
			mGenerateId=generateId;
			mKey=key;
		}
		
		/**
		 * @n<b>函数名称</b>     :decodeRes
		 * @brief 解析资源类型的GIF图片
		 * @version    Ver 1.3.3_modularization
		 * @param  @param resid
		 * @return void
		 * @<b>作者</b>          :  cb
		 * @<b>创建时间</b>      :  2014-3-13下午7:59:39      
		*/
		private void decodeRes(int resid){
			InputStream stream=ApplicationVariable.INSTANCE.applicationContext.getResources().openRawResource(resid);
			Vector<GifFrame> frames =decodeStream(resid,stream);
			if (frames!=null){
				notifyDeocdeResult(mKey,mGenerateId);
				put(mKey, frames);
			}
		}
		
		/**
		 * @n<b>函数名称</b>     :decodeFile
		 * @brief 解析文件类型的GIF图片
		 * @version    Ver 1.3.3_modularization
		 * @param  @param path
		 * @return void
		 * @<b>作者</b>          :  cb
		 * @<b>创建时间</b>      :  2014-3-13下午7:59:48      
		*/
		private void decodeFile(String path){
			InputStream stream = null;
			Vector<GifFrame> frames = null;
			try {
				if (TextUtils.isEmpty(path)){
					return;
				}
				if (path.startsWith("smiley/smily_cat") || path.startsWith("smiley/smily_cos")){
					//猫表情
					AssetManager am = ApplicationVariable.INSTANCE.applicationContext.getResources().getAssets();
					try {
						stream = am.open(path);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}else{
					File file=new File(path);
					if (file==null || !file.exists()){
						return;
					}
					stream = new FileInputStream(file);	
				}
				frames = decodeStream(path,stream);
			} catch (FileNotFoundException e) {
				
			} finally {
				if (stream!=null){
					try {
						stream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (frames!=null){
					put(mKey, frames);
					notifyDeocdeResult(mKey,mGenerateId);
				}
			}
		}
		
		@Override
		public void run() {
//			Log.d("gifview","Decoding:"+mGenerateId+",key="+mKey);
			while (mIsClearing){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
					return;
				}
			}
			if (mKey instanceof String){
				String path=(String) mKey;
				decodeFile(path);
			}else{
				int resid=(Integer) mKey;
				decodeRes(resid);
			}
			if (!mMaps.containsKey(mKey) && !mIsClearing){
				//解析失败
				mBrokenGifList.add(mKey);
			}
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :notifyDeocdeResult
	 * @brief 通知GIF解析成功
	 * @version    Ver 1.3.3_modularization
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-13下午7:59:27      
	*/
	public void notifyDeocdeResult(Object key,String generateId){
		if (mIsClearing){
//			Log.d("gifview","cache is clear");
			return;
		}
		BaseCommonStruct struct=new BaseCommonStruct();
		int id=CIConst.CHAT_GIF_DECODE_FINISH_20069;
		if (key instanceof String){
			struct.sPara=generateId+"*"+(String) key;
		}else{
			struct.sPara=generateId+"*"+key;
		}
		CommonInterfaceManager.INSTANCE.CommonInterfaceID(CIConst.CHAT_MODELID, id, struct);
	}
	
	/**
	 * @n<b>函数名称</b>     :decodeStream
	 * @brief 解码GIF
	 * @version    Ver 1.3.3_modularization
	 * @param  @param key
	 * @param  @param stream
	 * @param  @return
	 * @return Vector<GifFrame>
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-20下午5:49:34      
	*/
	private Vector<GifFrame> decodeStream(Object key,InputStream stream){
		GifDecoder decoder=new GifDecoder();
		Vector<GifFrame> frames=null;
		int statu=GifDecoder.STATUS_FORMAT_ERROR;
		try {
			statu=decoder.read(stream);			
		} catch (OutOfMemoryError e) {
			//内存不够
		}
		try {
			if (statu==GifDecoder.STATUS_OK){
				//返回的状态是正常的，说明是一个GIF图片
				frames=decoder.getFrames();
				if (frames==null || frames.size()==0){
					//异常分支，一般不可能走到
					//return null
				}else{
					//return frames;
				}
			}else{
				//不是GIF图片或者内存不够用
			}
		} catch (Exception e) {
//			Log.d("gifview","decode error,key="+key+","+e.getMessage());
		} finally {
			mDecodingGifList.remove(key);
		}
		return frames;
		 
	}
	
	/**
	 * @n<b>函数名称</b>     :getLocalBitmap
	 * @brief 根据KEY获取本地图片
	 * @version    Ver 1.3.3_modularization
	 * @param  @param key
	 * @param  @return
	 * @return Bitmap
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-20下午5:49:04      
	*/
	public Bitmap getLocalBitmap(Object key){
		Vector<GifFrame> frames=mMaps.get(key);
		if (frames!=null){
			//取已解析的第一张图
			return frames.get(0).getBitmap();
		}
		if (mLocalBitmaps.containsKey(key)){
			return mLocalBitmaps.get(key);
		}
		Bitmap bmp=null;
		if (key instanceof String){
			String path=(String) key;
			if (path.startsWith("smiley/smily_cat") || path.startsWith("smiley/smily_cos")){
				bmp=Smileyhelper.getInstance().getImageFromAssetsFile(ApplicationVariable.INSTANCE.applicationContext, path);
			}else{
				bmp=BitmapFactory.decodeFile(path);	
			}
			if (bmp.getWidth()>mMaxWidth || bmp.getHeight()>mMaxWidth){
				bmp=BitmapToolkit.resizeBitmap(bmp, mMaxWidth, mMaxWidth);
			}
		}else{
			if (key instanceof Integer){
				bmp=BitmapFactory.decodeResource(ApplicationVariable.INSTANCE.applicationContext.getResources(), (Integer) key);
			}
		}
		if (bmp!=null){
			int rowbyte=bmp.getRowBytes();
			mNowSize+=rowbyte*bmp.getHeight();
			mLocalBitmaps.put(key, bmp);			
		}
		return bmp;
	}
	
	/**
	 * @n<b>函数名称</b>     :registCheckUsingKeyInterface
	 * @brief 注册监听
	 * @version    Ver 1.3.3_modularization
	 * @param  @param keyInterface
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-26下午4:40:53      
	*/
	public void registCheckUsingKeyInterface(ICheckUsingKeyInterface keyInterface){
		if (mCheckUsingKeyInterfaces.contains(keyInterface)){
			return;
		}
		mCheckUsingKeyInterfaces.add(keyInterface);
	}
	
	public void unregistCheckUsingKeyInterface(ICheckUsingKeyInterface keyInterface){
		mCheckUsingKeyInterfaces.remove(keyInterface);
	}
	
	public void debug(){
		Log.d("gif","=========inuse keys below");
		for (int i=0,size=mInuseKeys.size();i<size;i++){
			Log.d("gif", mInuseKeys.get(i).toString());
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :getDiskCacheDir
	 * @brief 获取缓存路径
	 * @version    Ver 1.3.3_modularization
	 * @param  @return
	 * @return File
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-26下午4:33:34      
	*/
	private File getDiskCacheDir(Object key){
		File dir=StorageUtils.getIndividualCacheDirectory(ApplicationVariable.INSTANCE.applicationContext,DIR);
		String name=MD5ArithmeticUtils.getMd5(key.toString());
		String subDirPath=dir.getAbsolutePath()+Configuration.separatorChar+name;
		File subDir=new File(subDirPath);
		if (!subDir.exists()){
			subDir.mkdirs();
		}
		return subDir;
	}
	
	
	
	/**
	 * @n<b>函数名称</b>     :reCaculateCacheSize
	 * @brief 重新计算当前使用的缓存
	 * @version    Ver 1.3.3_modularization
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-26下午5:15:53      
	*/
	private void reCaculateCacheSize(){
		synchronized (mMaps) {
			mNowSize=0;
			Iterator<Entry<Object,Vector<GifFrame>>> iterator=mMaps.entrySet().iterator();
			while (iterator.hasNext()){
				Entry<Object,Vector<GifFrame>> entry=iterator.next();
				if (entry==null){
					break;
				}
				Vector<GifFrame> frames=entry.getValue();
				if (frames!=null && !frames.isEmpty()){
					for (GifFrame gifFrame : frames) {
						if (gifFrame.image!=null && !gifFrame.image.isRecycled()){
							if (gifFrame.size==0){
								gifFrame.size=gifFrame.image.getRowBytes()* gifFrame.image.getHeight();
							}
							mNowSize+=gifFrame.size;
						}
					}
				}
			}
		}
	}
	
	public void deActive(){
		mIsActive=false;
		Log.d("gifview", "deActive:"+mIsActive);
	}
}
